GrADS Data Sets (appendix A)

This appendix provides details on describing data so that GrADS can read it. GrADS supports two basic data types: 1) gridded ; and 2) station or point observations. The data and meta data (or information about the data) are kept in separate files. The file which you open in GrADS is the data descriptor file (the meta data) or ".ctl" file. The .ctl is constructed to describe various data types and structures (e.g., binary and GRIB).

Data Descriptor File options

There is a new record in the data descriptor file:

options <keywords>

This obsolotes the "format" record and allows for a greater variety of binary data to be described and access (opened) by GrADS.

Some keywords:

options <yrev> <zrev> <sequential> <byteswapped> <template>

<big_endian> <little_endian>

sequential

specifies that the file was written in sequential unformatted I/O, where each record is an X/Y varying grid. Note that if you have only one X and one Y dimension in your file, each record in the file will be one element long (it may not be a good idea to write the file this way).

yrev

specifies that the Y, or latitude, dimension has been written in the reverse order from what GrADS has in the past assumed. An important thing to remember is that GrADS still presents the view that the data goes from south to north. The YDEF statement does not change; it still describes the transformation from a grid space going from south to north. The reversal of the Y axis is done as the data is being read from the data file.

zrev

indicates the data has been written into the file from top to bottom, rather than from bottom to top as GrADS has in the past assumed. The same considerations as Yrev apply.

The best way to insure independence of hardward for gridded data files is to specifiy the source platform of the data. This allows the data to worked on both type of hardware without having to worry about byte ordering.

big_endian

32-bit IEEE floats created on a big_endian platform (e.g., cray, sun, sgi and hp).

little_endian

32-bit IEEE floats created on a little_endian platform (e.g., iX86, and dec)

File headers

You may tell GrADS that your data file has a header. To do this, include the record in your descriptor file:

fileheader bytenum

where bytenum is the number of bytes in the header. GrADS will skip past this header, then treat the file as though it were a normal GrADS file after that point. This option is valid only for GrADS gridded data sets.

Byte ordering

Up until now, you have been able to specify that the byte ordering of your data is the reverse of the standard for your workstation. This was done via the 'byteswapped' keyword. You may now indicate the actual byte ordering of the data:

options big_endian

or

options little_endian

If the data is already in the correct order, no conversion is performed. If you then move the data set to another machine, conversion will be automatically performed. These options were added to facilatate moving data files and descriptor files between machines.

You may also now specify:

options byteswapped

The byteswapped record is obsolote. The byteswapped option should be specified on the options record.

Multiple file time series

GrADS now allows you to handle many actual data files as one GrADS file, if the individual data files are in a GrADS readable format, and if the files are split along time. In the initial implementation, the time(s) that are in each file are indicated by the file name.

An example of this might be hourly data, where each 24 hours has been placed in a separate file. Each file is named this way:

1may92.dat

2may92.dat

etc.

You indicate to GrADS that there are multiple files in this time series by giving a substitution template as the file name:

dset %d1%mc%y2.dat

and giving an options record that looks like:

options template

and specifying the time range and increment in the tdef record:

tdef 72 linear 0z1may1993 1hr

GrADS will figure out automatically that there are 24 times in each file, and what file names coorospond to what times. As you display data, GrADS will only open one file at a time. As you change times such that another file is referred to, the open file is closed, and the new file is opened.

Valid subsitutions are:

%y2 - 2 digit year (last 2 digits)

%y4 - 4 digit year

%m1 - 1 or 2 digit month

%m2 - 2 digit month (leading zero if needed)

%mc - 3 character month abbreviation

%d1 - 1 or 2 digit day

%d2 - 2 digit day

%h1 - 1 or 2 digit hour

%h2 - 2 digit hour

This support works on all supported GrADS data types (GrADS gridded, GRIB, GrADS station data). If you specify file format options, the options must apply equally to each file.

The real-time data on the DECstations makes use of this new feature. See the data descriptor files:

/data/wx/grads/sa.ctl

/data/wx/grads/sareps.ctl

/data/wx/grads/wx.ctl

for additional examples.

Gridded Data Sets

The GrADS gridded data set is a direct access binary data set. It may contain any number of variables at specified longitude, latitude, vertical, and time intervals.

GrADS views this data set as a giant array -- with X (longitude) varying the fastest, then Y (latitude), then Z (vertical level), then the variable type, then T (time).

It is easier for us to think of the data set in terms of a sequence of horizontal grids, where longitude and latitude vary. Each horizontal grid represents a particular variable at a particular height and time. Each horizontal grid is the same size in any particular GrADS data set (if you have grids of different sizes, you must create seperate data sets).

These grids are written to the data set in the following order: starting with a particular variable, grids for each vertical level (at a particular time) are written out in ascending order. Then the grids for the next variable are written out. When all the grids at a particular time have been written, grids for the next time are written.

The format of this data set is thus exactly the same as the COLA Pressure History format, except: there are no date/time records, and latitude varies from south to north (not north to south as in the pressure history data).

Each binary gridded data set is described by a data descriptor file, essentially a table of contents for the binary data set. Following is an example of such a file:

DSET ua.dat

TITLE Upper Air Data

UNDEF -9.99E33

XDEF 80 LINEAR -140.0 1.0

YDEF 50 LINEAR 20.0 1.0

ZDEF 10 LEVELS 1000 850 700 500 400 300 250 200 150 100

TDEF 4 LINEAR 0Z10apr1991 12hr

VARS 5

slp 0 0 sea level pressure

z 10 0 heights

t 10 0 temps

td 6 0 dewpoints

u 10 0 u winds

v 10 0 v winds

ENDVARS

The data descriptor file is 'free format', ie each entry is blank delimited and may appear in any column. Comment records start with an asterisk ('*') in column 1. Comments may not appear in the list of variable records (between the vars and endvars records). Records may not be more than 80 characters long.

In this example, the binary data set is named ua.dat, the undefined, or missing, data value is -9.99e33, there are 80 grid points in the X direction, 50 in the Y direction, 10 levels, 4 times, and 5 variables. The variables z, t, u, and v have 10 levels, the variable td has 6 levels, and the variable slp has one level (see below for a more specific description of each entry).

Think in terms of the X and Y data points at one level for one variable at one time being a horizontal grid. This grid is exactly in the same storage order as a FORTRAN array, in this case an array DIMENSION A(80,50). The first dimension always varies from west to east, the second from south to north.

In the above example the horizontal grids would be written in the following order:

          Time 1, Level    ?, Variable slp
          Time 1, Level 1000, Variable z
          Time 1, Level  850, Variable z
                 then levels 700, 500, 400, 300, 250, 200, then
          Time 1, Level  150, Variable z
          Time 1, Level  100, Variable z
          Time 1, Level 1000, Variable t
          Time 1, Level  850, Variable t
                 then levels 700, 500, 400, 300, 250, 200, then
          Time 1, Level  150, Variable t
          Time 1, Level  100, Variable t
          Time 1, Level 1000, Variable td
          Time 1, Level  850, Variable td
          Time 1, Level  700, Variable td
          Time 1, Level  500, Variable td
          Time 1, Level  400, Variable td
          Time 1, Level  300, Variable td
          Time 1, Level 1000, Variable u
          Time 1, Level  850, Variable u
                 then levels 700, 500, 400, 300, 250, 200, then
          Time 1, Level  150, Variable u
          Time 1, Level  100, Variable u
          Time 1, Level 1000, Variable v
          Time 1, Level  850, Variable v
                 then levels 700, 500, 400, 300, 250, 200, then
          Time 1, Level  150, Variable v
          Time 1, Level  100, Variable v
          Time 2, Level    ?, Variable slp
          Time 2, Level 1000, Variable z
          Time 2, Level  850, Variable z
          Time 2, Level  700, Variable z
          Time 2, Level  500, Variable z
          Time 2, Level  400, Variable z
                    .
                    .
                    .
                   etc

A description of each record in the GrADS data descriptor file follows:

DSET data-set-name

This entry specifies the name of the binary data set. It may be entered in mixed case.

If the binary data set is in the same directory as the data descriptor file, you may enter the filename in the data descriptor file without a full path name by prefixing it with a ^ character. For example, if the data descriptor file is:

/data/wx/grads/sa.ctl

and the binary data file is:

/data/wx/grads/sa.dat

you could use the following file name in the data descriptor file:

DSET ^sa.dat

instead of:

DSET /data/wx/grads/sa.dat

As long as you keep the two files together, you may move them to any directory without changing the entries in the data descriptor file.

TITLE string

A brief description of the contents of the data set. This will be displayed during a QUERY command, so it is helpful to put meaningful information here.

UNDEF value

The undefined, or missing, data value. GrADS operations and graphics routines will ignore data with this value from this data set.

OPTIONS BYTESWAPPED

Indicates the binary data file is in reverse byte order from the normal byte order of the machine. This would happen if you sent a file in binary fromat from, for example, a Sun to a PC. Putting this keyword in the descriptor file tells GrADS to swap the byte order as the data is being read.

XDEF number <LINEAR start increment>

<LEVELS value-list>

Defines the mapping between grid values and longitude. Specifically:

number -- the number of grid values in the X direction, specified as an integer number. Must be >= 1.

LINEAR or LEVELS -- Indicates the grid mapping type.

For LINEAR:

start -- the starting longitude, or the longitude for X = 1. Specified as a floating point value, where negative indicates degrees west.

increment -- the spacing between grid value in the X direction. It is assumed that the X dimension values go from west to east. Specified as a positive floating value.

For LEVELS:

value-list -- List of 'number' values representing the longitude of each X dimension. May start and continue on the next record in the descriptor file (records may not be > 80 characters). There must be at least 2 levels (otherwise use LINEAR mapping).

YDEF number mapping start <increment>

<LEVELS value-list>

Defines the mapping between grid values and latitude. Specifically:

number -- the number of grid values in the X direction, specified as an integer number.

mapping -- mapping type, specified as a keyword.

Valid are:

LINEAR -- Linear mapping

GAUSR15 -- Gaussian R15 latitudes

GAUSR20 -- Gaussian R20 latitudes

GAUSR30 -- Gaussian R30 latitudes

GAUSR40 -- Gaussian R40 latitudes

start -- For LINEAR mapping, the starting latitude, ie the latitude for Y = 1, and is specified as a floating point value, with negative indicating degrees south. For GAUSRxx mapping, the start value indicates the first gaussian grid number, where 1 would be the southernmost gaussian grid latitude.

increment -- the spacing between grid values in the Y direction. It is assumed that the Y dimension values go from south to north. Specified as a positive floating point value. Used only for LINEAR mapping.

For LEVELS:

value-list -- List of 'number' values representing the latitude of each X dimension. May start and continue on the next record in the descriptor file (records may not be > 80 characters). There must be at least 2 levels (otherwise use LINEAR mapping).

Examples of specifying GAUSRxx mapping:

YDEF 20 GAUSR40 15

Indicates that there are 20 Y dimension values which start at Gaussian Latitude 15 (64.10 south) on the Gaussian R40 grid. Thus the 20 values would coorospond to Latitudes:

-64.10, -62.34, -60.58, -58.83, -57.07, -55.32, -53.56,

-51.80, -50.05, -48.29, -46.54, -44.78, -43.02, -41.27,

-39.51, -37.76, -36.00, -34.24, -32.49, -30.73

YDEF 102 GAUSR40 1

The entire gaussian grid is present, starting at the southernmost latitude (-88.66).

ZDEF number mapping <start increment>

<value-list>

Defines the mapping between grid values and pressure level. Specifically:

number -- the number of grid values in the X direction, specified as an integer number.

mapping -- mapping type, specified as a keyword.

Valid are:

LINEAR -- Linear mapping

LEVELS -- Arbitrary pressure levels

start -- when mapping is LINEAR, this is the starting value, or the value when Z=1.

increment -- when mappeing is LINEAR, the increment in the Z direction, or from lower to higher. This may be a negative value, for example:

ZDEF 10 LINEAR 1000 -100

indicating that the data is for levels 1000, 900, 800, 700, etc.

value-list -- when the mapping is LEVELS, the specific levels are simply listed in ascending order. If there is only one level, use LINEAR, since LEVELS implies at least two levels.

TDEF number LINEAR start-time increment

Defines the mapping between grid values and time. Specifically:

number -- the number of times in the data set. Specified as an integer number.

start-time -- The starting date/time value, specified in GrADS absolute date/time format. This is the value when T=1. The date/time format is:

hh:mmZddmmmyyyy

where:

hh = hour (two digit integer)

mm = minutes (two digit integer)

dd = day (one or two digit integer)

mmm = month (jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec)

yyyy = year (two or four digit integer. two digits implies a year between 1950 and 2049).

If not specified, hh defaults to 00, mm defaults to 00, and dd defaults to 1. The month and year must be specified. No intevening blanks are allowed in a GrADS absolute date/time.

Examples:

12Z1JAN1990

14:20Z22JAN1987

JUN1960

increment -- time increment. Specified in GrADS time increment format:

vvkk

where:

vv = an integer number, 1 or 2 digits

kk = an increment keyword,

mn = minutes

hr = hours

dy = days

mo = months

yr = year

Examples:

20mn -- increment is 20 minutes

1mo -- increment is 1 month

2dy -- increment is 2 days

Some examples of a TDEF statement:

TDEF 24 LINEAR 00Z01JUN1987 1HR

The data set has 24 times, starting at 00Z on 1 Jun, 1987, with an increment of 1 hour.

TDEF 30 LINEAR 2JUN1988 1DY

The data set has 30 times, starting at 00Z on 2 Jun, 1988, with an increment of 1 day.

VARS number

Indicates the start of the records describing the variables in the data set.

number -- the number of variable records

Each variable record is in the following format:

abrev levs units description

abrev -- a 1 to 8 character abbreviation for this variable. This abreviation must start with an alphabetic character (a-z) and be composed of alphabetic characters and numbers. This abbreviation will be the "name" the variable is accessed by from within GrADS.

levs -- an integer value specifying the number of levels this variable has in the data set. It may not exceed the number of levels in the ZDEF statement. A levs value of 0 indicates this variable has one "level" that does not coorospond to a vertical level. An example would be a surface variable.

units - Reserved for future use. Put a value of 99 here.

description - A text description of the variable, max 40 characters.

After the last variable record comes the ENDVARS statement. This ends the GrADS data descriptor file.

Station Data Sets

Station data sets are written to a binary file one report at a time. The only ordering required is that the station reports be grouped within the file into some time interval. For example, the time interval for upper air observations might be 12 hours.

Variables within each report are split into two groupings. Each variable is either a surface variable, thus can be reported at most once per report, or it is a level dependent variable, thus can be reported at a number of different levels within one report.

Byte-ordering control for station data files: You may now specify byteswapping (byteswapped, big_endian, or little_endian) for station data files. The stnmap utility, and GrADs, will perform the necessary conversion. Station map files must still be created on the machine where they are to be used.

Station map files (and GRIB index files) will be made portable before Version 1.4 is released in production.

The format of a station report in the binary station data file is:

- A header which provides information about the location of the station.

- Surface variables, if any

- Level dependent variables, if any

The header is described by the following C language data structure:

        struct rpthdr {
          char id[8];          /* Character station id           */
          float lat;           /* Latitude of report             */
          float lon;           /* Longitude of report            */
          float t;             /* Time in relative grid units    */
          int  nlev;           /* Number of levels following     */
          int flag;            /* Level independent var set flag */
        };

A detailed description of each header entry follows:

id - The station identifier. This is a 1 to 7 character identifier that should identify the station uniquely. It may be assigned arbitrarily; ie. the stations could be numbered in some arbitrary order.

lat - The Y dimension location of the station in world coordinates, typically latitude.

lon - The X dimension location of the station in world coordinates, typically longitude.

t - The time of this report, in relative grid units. This refers to the way the stations are grouped in time. For example, if you are working with surface airways reports, you would probably have a time grouping interval of one hour. If you wanted to treat the report times of each report as being exactly on the hour, you would set t to 0.0. If the report was for 12:15pm, and you were writing the time group for 12pm, you would set t to be 0.25. Thus, t would typically have the range of -0.5 to 0.5.

nlev - Number of data groups following the header. This is the count of the one surface group, if present, plus the number of level dependent groups. Is set to zero to mark the end of a time group in the file.

flag - If zero, there are no surface variables following the header. If one, then there are surface variables following the header.

Following the header, the data for this report is written. The first group of data would be all the surface variables if present. Whether or not the surface variable (if any) are present is determined by the flag in the header. If present, then all the surface varialbes must be written -- missing variables should have the missing data value provided. Thus, each surface variable group will be the same size for each report in the file.

The surface variables are written out as floating point numbers. The ordering of the variables must be the same in each report, and is the ordering that will be given in the data descriptor file.

Following the surface variable group, any number of level dependent groups may be written. The number of total data groups is provided in the header. Each level dependent group must have all the level dependent variables present, even if they are filled with the missing data value. Thus, each level dependent group will be the same size for all levels and all reports in the file.

The level dependent group is written out as follows:

level -- floating point value giving the Z dimension value in world coordinates for this level.

variables -- The level dependent variables for this level.

After all the reports for one time grouping have been written, a special header (with no data groups) is written to indicate the end of the time group. The header has an nlev value of zero. The next time group may then start immediately after. A time group with no reports would still contain the time group terminator header record (ie, two terminators in a row).

GrADS station data files must be written as UNIX stream data sets without any imbedded record descriptor information. This is easily done from a C program. From a FORTRAN program, it usually requires a system-dependent option in the OPEN statement. For example, in DEC FORTRAN one can use the

RECORDTYPE='STREAM'

option to avoid having record descriptor information imbedded in the output file. Examples of C and FORTRAN programs to create station data sets are provided later in this document.

Station Data Descriptor File

The format for the data descriptor file for station data is similar to the format for a gridded data set. An example of a station data descriptor file is:

dset ^ua.reps

dtype station

stnmap ^ua.map

undef -999.0

title Real Time Upper air obs

tdef 10 linear 12z18jan1992 12hr

vars 12

slp 0 99 SLP

ts 0 99 Temps

ds 0 99 Dewpoints

us 0 99 U Winds

vs 0 99 V Winds

z 1 99 Heights

t 1 99 Temps

d 1 99 Dewpoints

u 1 99 U Winds

v 1 99 V Winds

endvars

Note the differences between this descriptor file and a grid descriptor file:

DTYPE record -- specify a data type of: station.

STNMAP record -- gives the file name of the station mapping file. This file is created by the

stnmap utility, which will be described later.

XDEF, YDEF, ZDEF records -- not specified.

TDEF record -- describes the time grouping interval and the number of time groups in the file.

VAR records -- surface variables must come first, and are given a zero for the number-of-levels field. Level dependent variables are listed after the surface variables, and are given a one in the number-of-levels field.

STNMAP Utility

Once the data set has been written, and the descriptor file created, you should then create the station map file by running the stnmap utility. This utility writes out hash table and/or link list information that allows GrADS to access the report data more efficiently. The utility will prompt for the name of the data descriptor file.

If you change the data file -- perhaps by appending another time group -- you will also have to change the descriptor file to reflect the changes -- the new number of times for example -- and then rerun the stnmap utility.

Examples of Creating a Gridded Data Set

On a workstation, the binary GrADS data sets need to be created as a 'stream' data set, ie, it should not have the normal FORTRAN record descriptor words imbedded in it. This can be done from FORTRAN using direct access I/O:

          REAL  Z(72,46,16)
              .
              .
          OPEN (8,FILE='grads.dat',FORM='UNFORMATTED',
         &   ACCESS='DIRECT',RECL=72*46)
              .
              .
          IREC=1
          DO 10 I=1,18
            WRITE (8,REC=IREC) ((Z(J,K,I),J=1,72),K=1,46)
            IREC=IREC+1
      10  CONTINUE

This example writes out 16 levels of one variable to a file in direct access format. We are really writing the data out sequentially, and using direct access to avoid having the record descriptor words written. There may be options in your compiler to do this more directly, or you ay wish to write the data using a C program.

Another simple sample might be:

          REAL X(100)
          DO 10 I=1,100
            X(I)=I
      10  CONTINUE
          OPEN (8,FILE='samp.dat',FORM='UNFORMATTED',ACCESS='DIRECT',
         &         RECL=100)
          WRITE (8,REC=1) X
          STOP
          END

The associated descriptor file:

          DSET 	samp.dat
          TITLE 	Sample Data Set
          UNDEF 	-9.99E33
          XDEF 	100 LINEAR 1 1 
          YDEF 	1 LINEAR 1 1 
          ZDEF 	1 LINEAR 1 1 
          TDEF 	1 LINEAR 1JAN2000 1DY
          VARS 	1 
          x  0  99  100 Data Points
          ENDVARS

Once created, you can use this data set to experiment with GrADS data functions, such as:

display sin(x/50)

Examples of Creating Station Data Sets

Lets say you have a data set with monthly rainfall:

          Year Month Stid        Lat    Lon     Rainfall
          1980    1  QQQ         34.3   -85.5   123.3
          1980    1  RRR         44.2   -84.5    87.1
          1980    1  SSS         22.4   -83.5   412.8
          1980    1  TTT         33.4   -82.5    23.3
          1980    2  QQQ         34.3   -85.5   145.1
          1980    2  RRR         44.2   -84.5   871.4
          1980    2  SSS         22.4   -83.5   223.1
          1980    2  TTT         33.4   -82.5    45.5
            .
            .

A FORTRAN program in DEC FORTRAN to write this data set in GrADS format might be:

             CHARACTER*8 STID
       C
             OPEN (8,NAME='rain.ch') 
             OPEN (10,NAME='rain.dat',FORM='UNFORMATTED',
            &            RECORDTYPE='STREAM')
       C
             IFLAG = 0
       C  
       C  Read and Write
       C
       10    READ (8,9000,END=90) IYEAR,IMONTH,STID,RLAT,RLON,RVAL
       9000  FORMAT (I4,3X,I2,2X,A8,3F8.1)
             IF (IFLAG.EQ.0) THEN
               IFLAG = 1
               IYROLD = IYEAR
               IMNOLD = IMONTH
             ENDIF
       C
       C  If new time group, write time group terminator.
       C  Assuming no empty time groups.
       C
             IF (IYROLD.NE.IYEAR.OR.IMNOLD.NE.IMONTH) THEN
               NLEV = 0
               WRITE (10) STID,RLAT,RLON,TIM,NLEV,NFLAG
             ENDIF
             IYROLD = IYEAR
             IMNOLD = IMONTH
       C
       C  Write this report
       C
             TIM = 0.0
             NLEV = 1
             NFLAG = 1
             WRITE (10) STID,RLAT,RLON,TIM,NLEV,NFLAG
             WRITE (10) RVAL
             GO TO 10
       C
       C  On end of file write last time group terminator.
       C
       90    CONTINUE
             NLEV = 0
             WRITE (10) STID,RLAT,RLON,TIM,NLEV,NFLAG
             STOP
             END

For a different compiler, you would need to determine the appropriate OPEN statement to write a stream data set.

An equivalent C program might be:

      #include <stdio.h>
      /* Structure that describes a report header in a stn file */
 
      struct rpthdr {
        char id[8];           /* Character station id           */
        float lat;            /* Latitude of report             */
        float lon;            /* Longitude of report            */
        float t;              /* Time in relative grid units    */
        int  nlev;            /* Number of levels following     */
        int flag;             /* Level independent var set flag */
      } hdr;
      main () {
      FILE *ifile, *ofile;
      char rec[80];
      int flag,year,month,yrsav,mnsav,i;
      float val;
        /* Open files */
        ifile = fopen ("rain.ch","r");
        ofile = fopen ("rain.dat","wb");
        if (ifile==NULL || ofile==NULL) {
          printf ("Error opening files\n");
          return;
        }
        /* Read, write loop */
        flag = 1;
        while (fgets(rec,79,ifile)!=NULL) {
          /* Format conversion */
          sscanf (rec,"%i %i ",&year,&month);
          sscanf (rec+20," %g %g %g",&hdr.lat,&hdr.lon,&val);
          for (i=0; i<8; i++) hdr.id[i] = rec[i+11];
          /* Time group terminator if needed */
          if (flag) {
            yrsav = year;
            mnsav = month;
            flag = 0;
          }
          if (yrsav!=year || mnsav!=month) {
            hdr.nlev = 0;
            fwrite (&hdr,sizeof(struct rpthdr), 1, ofile);
          }
          yrsav = year;
          mnsav = month;
          /* Write this report */
          hdr.nlev = 1;
          hdr.flag = 1; 
          hdr.t = 0.0;
          fwrite (&hdr,sizeof(struct rpthdr), 1, ofile);
          fwrite (&val,sizeof(float), 1, ofile);
        }
        hdr.nlev = 0;
        fwrite (&hdr,sizeof(struct rpthdr), 1, ofile);
      }

Once the binary data file has been written, create the descriptor file. It would look something like this:

        dset   	rain.dat
        dtype  	station
        stnmap 	rain.map
        undef  	-999.0
        title  	Rainfall 
        tdef  	12 linear jan1980 1mo
        vars 	1
        p  		0  99  Rainfall
        endvars

Then run the stnmap utility to create the station map file. You can then open and display this data from within GrADS.